package com.example.demo.interceptor;

import com.example.demo.common.PassToken;
import com.example.demo.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * token拦截器
 *
 * @author shiwen
 * @date 2020/7/20
 */

@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    /**
     * 在操作之前进行拦截校验的操作
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器拦住了......");
        // 无论如何都放行，具体能不能操作还是在具体的操作中判断
        // 拦截器只是负责把头请求头重包含token的令牌进行解析
        String header = request.getHeader("token");
        // 判断是否为空,如果请求token为空的话直接权限不足
        if (header == null || "".equals(header)) {
            throw new RuntimeException("权限不足");
        }
        // 这里我们再定义了一个PassToken的注解，用于跳过token拦截器的校验
        if (handler != null) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            //检查是否有passtoken注释，有则跳过认证
            if (method.isAnnotationPresent(PassToken.class)) {
                PassToken passToken = method.getAnnotation(PassToken.class);
                if (passToken.required()) {
                    return true;
                }
            }
        }
        // 得到token令牌，这里获取的是value的值，而不是key的值，比如：token:adewbvcbcs.adazccz.rnbgfdch的话，就是获取value的值
        String token = header;
        try {
            // 解析令牌
            Claims claims = jwtUtil.parseJWT(token);
            // 获取存储在claims中的角色roles
            String roles = (String) claims.get("roles");
            // 判断roles是否为空或者roles角色是否为admin
            if (!"admin".equals(roles) || roles == null) {
                throw new RuntimeException("权限不足");
            }
            // 角色不为空且token不为空
            if (roles != null && !"admin".equals(roles)) {
                request.setAttribute("claims",   token);
            }
        } catch (Exception e) {
            // return true 放行 : false 不放行
            throw new RuntimeException("令牌有误");
        }
        return true;
    }

}